package com.example.springboot.config.postProcessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Objects;

/**
 * 没有循环依赖的代理对象的生成
 * 从该实现可以知道，BeanPostProcessor可以有多个，而且会按照顺序依次处理。如果只要其中的任意一个返回null，
 * 则后续的BeanPostProcessor的postProcessBeforeInitialization将不会再处理了。
 *
 * @Author:ChenZhangKun
 * @Date: 2021/5/17 16:02
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 在这里生成代理对象
        // 以CZK进行举例
        if (Objects.equals("CZK", beanName)) {
            // 生成代理对象
            // 拿到类加载器
            Class<?> clazz = bean.getClass();
            ClassLoader classLoader = clazz.getClassLoader();
            // 拿到接口
            Class<?>[] interfaces = clazz.getInterfaces();
            System.out.println(bean.getClass());
            // 动态代理
            Object finalBean = bean;
            bean = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("执行CZK的print方法之前");
                    // 执行方法
                    Object invoke = method.invoke(finalBean, args);
                    System.out.println("执行CZK的print方法之后");
                    return invoke;
                }
            });
            return bean;
        } else {
            return bean;
        }
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
